

#include "BlockQueue.hpp"
#include "My_pthread.hpp"
#include "Task.hpp"
#include <vector>
#include <string>
using namespace ThreadModule;
int a = 10;

using BlockQueue_t = BlockQueue<Task>;

void Consumer(BlockQueue_t *bp)
{
    // sleep(3);
    while (1)
    {
        // 取出任务
        Task t;
        bp->Outqueue(&t);
        // 执行任务
        t.Excute();

        // 打印结果
        std::cout << "I am consumer pthread: consume :  " << t.ResultToString() << std::endl;
        sleep(1);
    }
}

void Productor(BlockQueue_t *bp)
{
    srand(time(nullptr) ^ pthread_self());
    // int cnt = 10;
    while (1)
    {
        // 生产者，生产任务：
        int a = rand() / 1000000000;
        int b = rand() / 1000000000;
        Task t(a, b);

        // 任务入队列
        bp->Enqueue(t);
        std::cout << "I am Productor pthread: product : " << t.ProcessToString() << std::endl;
        sleep(1);
        // cnt++;
    }
}

void comm(std::vector<Thread<BlockQueue_t *>> &ptd, int nums, func_t<BlockQueue_t *> _func, BlockQueue_t *bp)
{
    for (int i = 0; i < nums; i++)
    {
        std::string name = "Pthread-" + std::to_string(i);
        ptd.emplace_back(_func, bp, name);
        ptd.back().Start();
    }
}

void StartConsumer(std::vector<Thread<BlockQueue_t *>> &ptd, int nums, BlockQueue_t *bp)
{
    comm(ptd, nums, Consumer, bp);
}

void StartProductor(std::vector<Thread<BlockQueue_t *>> &ptd, int nums, BlockQueue_t *bp)
{

    comm(ptd, nums, Productor, bp);
}

void Wait_all(std::vector<Thread<BlockQueue_t *>> &ptd)
{
    for (auto &pb : ptd)
    {
        pb.Join();
    }
}

int main()
{
    BlockQueue_t *bp = new BlockQueue_t(5);
    std::vector<Thread<BlockQueue_t *>> Ptd;
    // vector里面存储的是一个自定义线程，线程封装了
    //   pthread_t _tid;
    //   std::string _threadname;
    //   T _data; // 为了让所有的线程访问同一个全局变量，然后线程里的的全局变量就是阻塞队列
    //   func_t<T> _func;
    //   bool _stop;

    StartConsumer(Ptd, 1, bp);
    StartProductor(Ptd, 1, bp);

    Wait_all(Ptd);
}